import numpy as np
import math
def checkit(loads,oldlds,tol,converged):
    #检查前后两个量的收敛性
  neq=loads.shape[0]
  big=0.0 
  converged[:]=True
  for i in range(1,neq+1):
    if abs(loads[i-1,0])>big:
      big=abs(loads[i-1,0])
  for i in range(1,neq+1):
    if abs(loads[i-1,0]-oldlds[i-1,0])/big>tol:
      converged[:]=False
n=3
converged=np.array([False])
r=np.zeros((n,1))
u=np.zeros((n,1))
xnew=np.zeros((n,1))
a=np.array([[16,4,8],[4,5,-4],[8,-4,22]],dtype=np.float)
b=np.array([[4],[2],[5]],dtype=np.float)
x=np.array([[1],[1],[1]],dtype=np.float)
tol=1.0e-5
limit=100
print('系数矩阵')
print(a[:])
print('右手边向量',b[:,0])
print('初始猜测值',x[:,0])
print('前几次迭代值')
r[:]=b[:]-np.dot(a,x)
iters=0
while(True):
    iters=iters+1
    u[:]=np.dot(a,r)
    alpha=np.dot(np.transpose(r),r)/np.dot(np.transpose(r),u)
    xnew[:]=x[:]+alpha*r[:]
    r[:]=r-alpha*u[:]
    if iters<5:
        print(x[:,0])
    checkit(xnew,x,tol,converged)
    if converged==True or iters==limit:
        break
    x[:,0]=xnew[:,0]
print('到收敛需要迭代次数',iters)
print('解向量',x[:,0])   